<?php

namespace App\Service\act;

use App\Amqp\Producer\TaskProgressProducer;
use App\Enum\EnumType;
use App\Exception\ErrMsgException;
use App\Service\BaseService;
use Hyperf\Amqp\Producer;
use Hyperf\Context\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use function Hyperf\Support\env;

/**
 * 用户任务服务
 */
class UserTaskService extends BaseService
{
    // 表名
    protected static string $tbName = 'act_user_task';

    /**
     * 获取用户任务列表
     * @param array $params
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \RedisException
     */
    public static function getUserTaskList(array $params = []): array
    {
        // 字段
        $field = empty($params['field']) ? ['*'] : $params['field'];
        return self::getUidPartTb(self::$tbName, $params['uid'])
            ->when(!empty($params['act_id']), function ($query) use ($params) {
                $query->where('act_id', $params['act_id']);
            })
            ->when(!empty($params['uid']), function ($query) use ($params) {
                $query->where('uid', $params['uid']);
            })
            ->when(!empty($params['task_id']), function ($query) use ($params) {
                $query->where('task_id', $params['task_id']);
            })
            ->when(!empty($params['task_ids']), function ($query) use ($params) {
                $query->whereIn('task_id', $params['task_ids']);
            })
            ->orderBy('curr_times')
            ->select($field)
            ->get()->toArray();
    }

    /**
     * 获取用户任务进行状态列表
     * @param array $params
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \RedisException
     */
    public static function getUserTaskForApi(array $params = [])
    {
        $params['task_key'] = $params['task_key'] ?? env('ACT_15DATY_TASK_KEY', '15days');
        // 获取数据
        $taskList = TaskService::getTaskList($params, true);
        // 用户任务完成进度
        $userTasks = [];
        $userActCurrTimes = 1;
        if (!empty($params['uid'])) {
            $params['task_ids'] = array_column($taskList, 'task_id');
            $userTasks_ = self::getUserTaskList($params);
            foreach ($userTasks_ as $ut) {
                $userTasks[$ut['task_id'].'_'.$ut['curr_times']] = $ut;
            }
            // 用户活动任务当前进行轮次
            $userActCurrTimes = $userTasks_ ? max(array_column($userTasks_, 'curr_times')) : $userActCurrTimes;
        }

        // 检测用户最后一个任务当前轮次是否完成
        $userLastTaskId = $taskList[count($taskList) - 1]['task_id'];
        $newTimesStartTime = 0; // 新轮次开启时间
        if (isset($userTasks[$userLastTaskId.'_'.$userActCurrTimes])) {
            $userCurrTimesLastTask = $userTasks[$userLastTaskId.'_'.$userActCurrTimes]; // 用户本轮次最后一个任务
            if ($userCurrTimesLastTask['status'] == EnumType::USER_TASK_STATUS_COMPLETED) { // 最后一个任务已完成
                $newTimesStartTime = strtotime(
                    '+1 day',
                    strtotime(date(self::$dateFormat, strtotime($userCurrTimesLastTask['complete_time'])))
                );
            }
        }

        $list = [];
        foreach ($taskList as $v) {
            // 任务总进度
            $checkField = TaskService::getTaskConditionField($v['condition_type']); // 任务条件检测字段
            $item = [
                'task_id' => $v['task_id'],
                'task_name' => $v['task_name'],
                'task_brief' => $v['task_brief'],
                'task_icon' => $v['task_icon'],
                'total_progress' => $v['task_conditions'][$checkField['progress_value']],
                'complete_progress' => 0,
                'task_status' => EnumType::TASK_STATUS_NOT_STARTED,
                'prize_list' => $v['prize_list'],
            ];

            // 新的轮次开始
            if ($newTimesStartTime && time() >= $newTimesStartTime) {
                $list[] = $item;
                continue;
            }

            // 用户已完成进度
            if (isset($userTasks[$v['task_id'].'_'.$userActCurrTimes])) {
                $ut = $userTasks[$v['task_id'].'_'.$userActCurrTimes];
                $ut['status'] == EnumType::USER_TASK_STATUS_COMPLETED && $item['total_progress'] = $ut['total_progress'];
                $item['complete_progress'] = $ut['complete_progress'];

                // 任务状态
                $item['task_status'] = match ($ut['status']) {
                        EnumType::USER_TASK_STATUS_IN_HAND => EnumType::TASK_STATUS_IN_HAND,
                        EnumType::USER_TASK_STATUS_COMPLETED => EnumType::TASK_STATUS_COMPLETED,
                        EnumType::USER_TASK_STATUS_NOT_COMPLETED => EnumType::TASK_STATUS_NOT_COMPLETED
                    };
            }

            $list[] = $item;
        }

        return $list;
    }

    /**
     * 用户游戏下注变更任务进度
     * @param int $uid
     * @param int $amount
     * @param int $gameId
     * @param int $terracesId
     * @param array $cloudExistCTypes // 可能存在的条件
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \RedisException
     */
    public static function userGameBetChangeTaskProgress(int $uid, int $amount, int $gameId = 0, int $terracesId = 0, array $cloudExistCTypes = []): void
    {
        try {
            // 可能存在的条件
//            $cloudExistCTypes = [
//                EnumType::TASK_CONDITION_TYPE_TERRACES_BET, EnumType::TASK_CONDITION_TYPE_TERRACES_WIN_BET,
//                EnumType::TASK_CONDITION_TYPE_GAME_BET, EnumType::TASK_CONDITION_TYPE_GAME_WIN_BET,
//            ];
            // 获取游戏下注任务存在的条件类型
            $hasTypes = TaskService::getTCTypesByGiveTypes($cloudExistCTypes, $amount, [
                'game_id' => $gameId,
                'terrace_id' => $terracesId,
            ]);
            if (empty($hasTypes)) return;

            // 消息队列完成任务进度
            $producer = ApplicationContext::getContainer()->get(Producer::class);
            foreach ($hasTypes as $ht => $val) {
                $producer->produce(new TaskProgressProducer([
                    'uid' => $uid,
                    'condition_type' => $ht,
                    'condition_value' => $amount,
                    'progress' => 1,
                    'is_group' => true,
                    // 任务筛选参数
                    'act_id' => env('ACT_15DATY_ID', 55),
                    'task_key' => env('ACT_15DATY_TASK_KEY', '15days'),
                ]));

                // 幸运转盘活动
                $producer->produce(new TaskProgressProducer([
                    'uid' => $uid,
                    'condition_type' => $ht,
                    'progress' => 1,
                    // 任务筛选参数
                    'act_id' => env('ACT_LUCKY_WHEEL_ID', 0)
                ]));
            }
        } catch (\Throwable $e) {
            self::logger()->error('UserTaskService.userGameBetChangeTaskProgress.Exception：' . $e->getMessage() . $e->getTraceAsString());
        }
    }

    /**
     * 用户充值变更任务进度
     * @param int $uid
     * @param int $amount 充值金额
     * @return void
     */
    public static function userRechargeChangeTaskProgress(int $uid, int $amount): void
    {
        try {
            // 消息队列完成任务进度
            $producer = ApplicationContext::getContainer()->get(Producer::class);
            $producer->produce(new TaskProgressProducer([
                'uid' => $uid,
                'condition_type' => EnumType::TASK_CONDITION_TYPE_RECHARGE,
                'condition_value' => $amount,
                'progress' => 1,
                'is_group' => true,
                // 任务筛选参数
                'act_id' => env('ACT_15DATY_ID', 55),
                'task_key' => env('ACT_15DATY_TASK_KEY', '15days'),
            ]));

            // 幸运转盘活动
            $producer->produce(new TaskProgressProducer([
                'uid' => $uid,
                'condition_type' => EnumType::TASK_CONDITION_TYPE_RECHARGE,
                'progress' => 1,
                // 任务筛选参数
                'act_id' => env('ACT_LUCKY_WHEEL_ID', 0),
            ]));
        } catch (\Throwable $e) {
            self::logger()->error('UserTaskService.userRechargeChangeTaskProgress.Exception：' . $e->getMessage() . $e->getTraceAsString());
        }
    }
}